﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

namespace BugSnapper
{
    public partial class frmFindDocument : Form
    {
        private delegate void GenericWindowsEventsHandler<TArgs>(object sender, TArgs e);
        private Logger Logger { get; set; }
        public frmFindDocument()
        {
            InitializeComponent();
            this.Logger = new Logger();
            try
            {
                this.txtDirectoryPath.Text = AppGlobal.RootFolderPath;
                this.SetDefaultDateValues();
                this.dgvDocumentViewer.DataSource = new List<DocumentFilterDataObject>();
            }
            catch (Exception ex)
            {
                this.txtDirectoryPath.Text = string.Empty;
                this.Logger.ProcessError(ex);
            }
        }
        private delegate void GenericEventsHandler();
        private void SetDefaultDateValues()
        {
            if (!IsDisposed)
            {
                if (!InvokeRequired)
                {
                    try
                    {
                        this.dtpEndDate.Value = DateTime.Today;
                        TimeSpan t = new TimeSpan(30, 0, 0, 0);
                        this.dtpStartDate.Value = DateTime.Today.Subtract(t);
                    }
                    catch (Exception ex)
                    {
                        this.Logger.ProcessError(ex);
                    }
                }
                else
                {
                    Invoke(new GenericEventsHandler(SetDefaultDateValues));
                }
            }
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if (!IsDisposed)
            {
                if (!InvokeRequired)
                {
                    try
                    {
                        using (FolderBrowserDialog folderBrowseDialog = new FolderBrowserDialog())
                        {
                            folderBrowseDialog.ShowDialog();
                            if (!string.IsNullOrEmpty(folderBrowseDialog.SelectedPath))
                            {
                                this.txtDirectoryPath.Text = folderBrowseDialog.SelectedPath;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        this.Logger.ProcessError(ex);
                    }
                }
                else
                {
                    Invoke(new GenericWindowsEventsHandler<EventArgs>(btnBrowse_Click), sender, e);
                }
            }
        }

        private static void AddRule(string filePath, string account, FileSystemRights rights, AccessControlType controlType)
        {
            FileSecurity fSecurity = File.GetAccessControl(filePath);
            fSecurity.AddAccessRule(new FileSystemAccessRule(account, rights, controlType));
            File.SetAccessControl(filePath, fSecurity);
        }
        private static void SetRule(string filePath, string account, FileSystemRights rights, AccessControlType controlType)
        {
            FileSecurity fSecurity = File.GetAccessControl(filePath);
            fSecurity.ResetAccessRule(new FileSystemAccessRule(account, rights, controlType));
            File.SetAccessControl(filePath, fSecurity);
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (!IsDisposed)
            {
                if (!InvokeRequired)
                {
                    List<DocumentFilterDataObject> listDf = new List<DocumentFilterDataObject>();
                    try
                    {
                        if (!string.IsNullOrEmpty(txtDirectoryPath.Text))
                        {
                            DirectoryInfo dr = new DirectoryInfo(this.txtDirectoryPath.Text);
                            DirectoryInfo[] directory = dr.GetDirectories();
                            FileInfo[] fl = dr.GetFiles();

                            int snum = 1;
                            if (!string.IsNullOrEmpty(this.txtSearchSelection.Text))
                            {
                                this.txtSearchSelectionErrorProvider.SetError(this.txtSearchSelection, "");
                                this.dtpSearchErrorProvider.SetError(this.dtpEndDate, "");
                                if (!this.chkDateSearch.Checked)
                                {
                                    if (fl.Count() > 0)
                                    {
                                        foreach (var item in fl)
                                        {
                                            if ((File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".doc" || File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".docx") && item.Name.ToLower().Contains(txtSearchSelection.Text.ToLower()))
                                            {
                                                try
                                                {
                                                    SetRule(item.FullName, "Everyone", FileSystemRights.Read, AccessControlType.Allow);
                                                    DocumentFilterDataObject df = new DocumentFilterDataObject();
                                                    df.SerialNumber = snum++;
                                                    df.CreationDate = item.CreationTime;
                                                    df.FileName = item.Name;
                                                    df.DirectoryPath = item.FullName;
                                                    listDf.Add(df);
                                                }
                                                catch (Exception ex)
                                                {
                                                    this.Logger.ProcessError(ex);
                                                }
                                            }
                                        }
                                    }
                                    if (directory.Count() > 0)
                                    {
                                        foreach (DirectoryInfo dir in directory)
                                        {
                                            FileInfo[] files = dir.GetFiles();
                                            foreach (var item in files)
                                            {
                                                if ((File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".doc" || File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".docx") && item.Name.ToLower().Contains(txtSearchSelection.Text.ToLower()))
                                                {
                                                    try
                                                    {
                                                        SetRule(item.FullName, "Everyone", FileSystemRights.Read, AccessControlType.Allow);
                                                        DocumentFilterDataObject df = new DocumentFilterDataObject();
                                                        df.SerialNumber = snum++;
                                                        df.CreationDate = item.CreationTime;
                                                        df.FileName = item.Name;
                                                        df.DirectoryPath = item.FullName;
                                                        listDf.Add(df);
                                                    }
                                                    catch (Exception ex)
                                                    {
                                                        this.Logger.ProcessError(ex);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    if (listDf.Count > 0)
                                    {
                                        this.dgvDocumentViewer.DataSource = listDf;
                                    }
                                    else
                                    {
                                        MessageBox.Show("0 Records Found, Please try again by modifying the search criteria or Check wether you have rights to read Current Directory or not....");
                                        this.dgvDocumentViewer.DataSource = documentFilterDataObjectBindingSource;
                                        txtSearchSelection.Text = string.Empty;
                                    }
                                }
                                else
                                {
                                    if (this.dtpEndDate.Value < this.dtpStartDate.Value && this.chkDateSearch.Checked)
                                    {
                                        this.dtpSearchErrorProvider.SetError(this.dtpEndDate, "The End Date can not be less than that of Start Date");
                                    }
                                    else
                                    {
                                        if (fl.Count() > 0)
                                        {
                                            foreach (var item in fl)
                                            {
                                                if ((File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".doc" || File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".docx") && item.Name.ToLower().Contains(txtSearchSelection.Text.ToLower()) && this.dtpStartDate.Value < item.CreationTime && item.CreationTime <= this.dtpEndDate.Value)
                                                {
                                                    try
                                                    {
                                                        SetRule(item.FullName, "Everyone", FileSystemRights.Read, AccessControlType.Allow);
                                                        DocumentFilterDataObject df = new DocumentFilterDataObject();
                                                        df.SerialNumber = snum++;
                                                        df.CreationDate = item.CreationTime;
                                                        df.FileName = item.Name;
                                                        df.DirectoryPath = item.FullName;
                                                        listDf.Add(df);
                                                    }
                                                    catch (Exception ex)
                                                    {
                                                        this.Logger.ProcessError(ex);
                                                    }
                                                }
                                            }
                                        }
                                        if (directory.Count() > 0)
                                        {
                                            foreach (DirectoryInfo dir in directory)
                                            {
                                                FileInfo[] files = dir.GetFiles();
                                                foreach (var item in files)
                                                {
                                                    if ((File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".doc" || File.Exists(item.FullName) && Path.GetExtension(item.Name).ToLower() == ".docx") && item.Name.ToLower().Contains(txtSearchSelection.Text.ToLower()) && this.dtpStartDate.Value < item.CreationTime && item.CreationTime <= this.dtpEndDate.Value)
                                                    {
                                                        try
                                                        {
                                                            SetRule(item.FullName, "Everyone", FileSystemRights.Read, AccessControlType.Allow);
                                                            DocumentFilterDataObject df = new DocumentFilterDataObject();
                                                            df.SerialNumber = snum++;
                                                            df.CreationDate = item.CreationTime;
                                                            df.FileName = item.Name;
                                                            df.DirectoryPath = item.FullName;
                                                            listDf.Add(df);
                                                        }
                                                        catch (Exception ex)
                                                        {
                                                            this.Logger.ProcessError(ex);
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        if (listDf.Count > 0)
                                        {
                                            this.dgvDocumentViewer.DataSource = listDf;
                                        }
                                        else
                                        {
                                            MessageBox.Show("0 Records Found, Please try again by modifying the search criteria or Check wether you have rights to read Current Directory or not....");
                                            this.dgvDocumentViewer.DataSource = documentFilterDataObjectBindingSource;
                                            txtSearchSelection.Text = string.Empty;
                                        }
                                    }
                                }

                            }
                            else
                            {
                                this.dgvDocumentViewer.DataSource = documentFilterDataObjectBindingSource.DataSource;
                                this.txtSearchSelectionErrorProvider.SetError(this.txtSearchSelection, "Please Enter Valid Search Criteria");
                            }
                        }
                        else
                        {
                            MessageBox.Show("Please select a Directory to search in...");
                        }
                    }
                    catch (Exception ex)
                    {
                        this.Logger.ProcessError(ex);
                        if (listDf.Count > 0)
                        {
                            this.dgvDocumentViewer.DataSource = listDf;
                        }
                        else
                        {
                            MessageBox.Show("0 Records Found, Please try again by modifying the search criteria or Check wether you have rights to read Current Directory or not....");
                            txtSearchSelection.Text = string.Empty;
                        }
                    }
                    finally
                    {
                        this.SetDefaultDateValues();
                    }
                }
                else
                {
                    Invoke(new GenericWindowsEventsHandler<EventArgs>(btnSearch_Click), sender, e);
                }
            }
        }

        private void dgvDocumentViewer_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (!IsDisposed)
            {
                if (!InvokeRequired)
                {
                    try
                    {
                        if (this.dgvDocumentViewer.SelectedRows.Count > 0)
                        {
                            string pathName = this.dgvDocumentViewer.SelectedCells[2].Value.ToString();
                            System.Diagnostics.Process.Start(pathName);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.Logger.ProcessError(ex);
                    }
                }
                else
                {
                    Invoke(new GenericWindowsEventsHandler<DataGridViewCellEventArgs>(dgvDocumentViewer_CellClick), sender, e);
                }
            }
        }


        private void chkDateSearch_CheckedChanged(object sender, EventArgs e)
        {
            if (!IsDisposed)
            {
                if (!InvokeRequired)
                {
                    try
                    {
                        if (this.chkDateSearch.Checked)
                        {
                            this.dtpEndDate.Enabled = true;
                            this.dtpStartDate.Enabled = true;
                        }
                        else
                        {
                            this.dtpEndDate.Enabled = false;
                            this.dtpStartDate.Enabled = false;
                            this.dtpSearchErrorProvider.Dispose();
                        }
                    }
                    catch (Exception ex)
                    {
                        this.Logger.ProcessError(ex);
                    }
                }
            }
            else
            {
                Invoke(new GenericWindowsEventsHandler<EventArgs>(chkDateSearch_CheckedChanged), sender, e);
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            if (!IsDisposed)
            {
                if (!InvokeRequired)
                {
                    try
                    {
                        this.Close();
                    }
                    catch (Exception ex)
                    {
                        this.Logger.ProcessError(ex);
                    }
                }
            }
            else
            {
                Invoke(new GenericWindowsEventsHandler<EventArgs>(btnClose_Click), sender, e);
            }
        }

        private void btnBrowse_MouseHover(object sender, EventArgs e)
        {
            try
            {
                this.toolTip1.SetToolTip(btnBrowse, "Browse");
            }
            catch (Exception ex)
            {
                this.Logger.ProcessError(ex);
            }
        }

        private void btnSearch_MouseHover(object sender, EventArgs e)
        {
            try
            {
                this.toolTip1.SetToolTip(btnSearch, "Search");
            }
            catch (Exception ex)
            {
                this.Logger.ProcessError(ex);
            }
        }

        private void btnClose_MouseHover(object sender, EventArgs e)
        {
            try
            {
                this.toolTip1.SetToolTip(btnClose, "Cancel");
            }
            catch (Exception ex)
            {
                this.Logger.ProcessError(ex);
            }
        }
    }
}
